#include "Orion_System.h"
#include "Orion_Gpio.h"
#include "MR88FX02.h"


void RCC_Configuration(enum_MainClkSrc clksrc,uint8_t ahbpres,enum_APBdiv apb_div)
{
	/*AHB divder*/
	SYSCTRL->SYSCLKDIV	&=	 ~((uint32_t)0xff); 			
	SYSCTRL->SYSCLKDIV	|=	 ahbpres; 						//b[7:0]     AHBCLK=48M/(1+AHBPRES)		(default:5)
	
	/*APB divder*/
	SYSCTRL->SYSCLKDIV	&=	 ~((uint32_t)0x7<<8); 			
	SYSCTRL->SYSCLKDIV	|=	 apb_div<<8; 			
	
	/*CLK SRC sel*/
	if(clksrc==InnerHSRC)
	{
		SYSCTRL->HSRCCON			|=0x01;													 // HSRC  Enable  default HSRC=48MHZ
		SYSCTRL->SYSCLKSEL 		&=	 ~((uint32_t)0x3); 					 // HSRC
		//SYSCTRL->SYSCLKSEL 		|=	 0; 											 //b[1:0] 0 -> HSRC, 1 -> HXTAL1	, 2->LSRC	,3->HXTAL2
	}
	else if(clksrc==ExterHXTAL2)
	{
		GPIO_Initial(GPIOA,Pin_Num_5,GPIO_ANALOG,Func0);
		GPIO_Initial(GPIOA,Pin_Num_6,GPIO_ANALOG,Func0);
		SYSCTRL->HXTALCON_b.XTAL2_EN_R=1;
		SYSCTRL->HXTALCON_b.XTAL2HEN=1;
		SYSCTRL->SYSCLKSEL 					 		&=	 ~((uint32_t)0x3); 
		SYSCTRL->SYSCLKSEL 					 		|=	 3; 											 //b[1:0] 0 -> HSRC, 1 -> HXTAL1	, 2->LSRC	,3->HXTAL2
	}
	else if(clksrc==ExterHXTAL1)
	{
		GPIO_Initial(GPIOA,Pin_Num_7,GPIO_ANALOG,Func0);
		GPIO_Initial(GPIOA,Pin_Num_8,GPIO_ANALOG,Func0);
		SYSCTRL->HXTALCON_b.XTAL1_EN_R=1;
		SYSCTRL->HXTALCON_b.XTAL1HEN=1;
		SYSCTRL->SYSCLKSEL_b.SYSCLKSEL=1;	//1:hxtal1
		SYSCTRL->SYSCLKSEL 					 		&=	 ~((uint32_t)0x3); 
		SYSCTRL->SYSCLKSEL 					 		|=	 1; 											 //b[1:0] 0 -> HSRC, 1 -> HXTAL1	, 2->LSRC	,3->HXTAL2
	}
	else if(clksrc==InnerLSCLK)
	{
		SYSCTRL->SYSCLKSEL_b.SYSCLKSEL=2;	
		SYSCTRL->SYSCLKSEL_b.LSCLKSEL=0; //1:xtal32k 0:inner 32k
		SYSCTRL->SYSCLKSEL 					 		&=	 ~((uint32_t)0x3); 
		SYSCTRL->SYSCLKSEL 					 		|=	 2; 											 //b[1:0] 0 -> HSRC, 1 -> HXTAL1	, 2->LSRC	,3->HXTAL2
	}
	else if(clksrc==ExterLSCLK)
	{
		GPIO_Initial(GPIOA,Pin_Num_7,GPIO_ANALOG,Func0);
		GPIO_Initial(GPIOA,Pin_Num_8,GPIO_ANALOG,Func0);
		SYSCTRL->HXTALCON_b.XTAL1_EN_R=1;
		SYSCTRL->HXTALCON_b.XTAL1LEN=1;
		SYSCTRL->SYSCLKSEL_b.SYSCLKSEL=2;	
		SYSCTRL->SYSCLKSEL_b.LSCLKSEL=1; //1:xtal32k 0:inner 32k
		SYSCTRL->SYSCLKSEL 					 		&=	 ~((uint32_t)0x3); 
		SYSCTRL->SYSCLKSEL 					 		|=	 2; 											 //b[1:0] 0 -> HSRC, 1 -> HXTAL1	, 2->LSRC	,3->HXTAL2
	}
}
void Device_CLK_Select(enum_Device_Name devname,uint8_t fsrc)
{
	if(set_beep1==devname)
		SYSCTRL->PERCKCFG_b.BEEP1CKSEL	=	fsrc;
	else if(set_led==devname)
		SYSCTRL->PERCKCFG_b.LEDCKSEL		=	fsrc;
	else if(set_adc==devname)
		SYSCTRL->PERCKCFG_b.ADCCKSEL		=fsrc;
	else if(set_lcd==devname)
		SYSCTRL->PERCKCFG_b.LCDCKSEL		=fsrc;
	else if(set_exti==devname)
		SYSCTRL->PERCKCFG_b.EXTICKSEL		=fsrc;
	else if(set_i2c0==devname)
		SYSCTRL->PERCKCFG_b.I2C0CKSEL		=fsrc;
	else if(set_wtim==devname)
		SYSCTRL->PERCKCFG_b.WTCKSEL			=fsrc;
	else if(set_beep0==devname)
		SYSCTRL->PERCKCFG_b.BEEP0CKSEL		=fsrc;
	else if(set_uart2==devname)
		SYSCTRL->PERCKCFG_b.UART2CKSEL		=fsrc;
	else if(set_uart1==devname)	
		SYSCTRL->PERCKCFG_b.UART1CKSEL		=fsrc;
	else if(set_uart0==devname)
		SYSCTRL->PERCKCFG_b.UART0CKSEL		=fsrc;
	else
		;
}
/*
typedef enum{
	set_beep1=0,
	set_led,
	set_adc,
	set_lcd,
	set_exti,
	set_i2c0,
	set_wtim,
	set_beep0,
	set_uart2,
	set_uart1,
	set_uart0,
	set_flash,
	set_sys,
	set_pmu,
	set_io,
	set_spi0,
	set_timer2,
	set_timer1,
	set_timer0,
	set_anactr,
	set_iwdg,
	set_crc,
	set_rambist,
}enum_Device_Name;

*/

void Device_CLK_Enable(enum_Device_Name devname,FunctionalState enable)
{
	switch(devname)
	{
        case set_beep1: {SYSCTRL->APBBCKCON_b.BEEP1BCKE=enable;SYSCTRL->PERCKEN_b.BEEP1CKEN=enable;	break;}
        case set_led: 	{SYSCTRL->APBBCKCON_b.LEDBCKE=enable;SYSCTRL->PERCKEN_b.LEDCKEN=enable;			break;}
        case set_adc:		{SYSCTRL->APBBCKCON_b.ADCBCKE=enable; 																			break;}
        case set_lcd: 	{SYSCTRL->APBBCKCON_b.LCDBCKE=enable;SYSCTRL->PERCKEN_b.LCDCKEN=enable;			break;}
        case set_exti: 	{																			SYSCTRL->PERCKEN_b.EXTICKEN=enable;		break;}
        case set_i2c0: 	{SYSCTRL->APBBCKCON_b.I2C0BCKE=enable;SYSCTRL->PERCKEN_b.I2C0CKEN=enable;		break;}
				case set_wtim: 	{SYSCTRL->APBBCKCON_b.WTIMBCKE=enable;SYSCTRL->PERCKEN_b.WTCKEN=enable;			break;}
				case set_beep0: {SYSCTRL->APBBCKCON_b.BEEP0BCKE=enable;SYSCTRL->PERCKEN_b.BEEP0CKEN=enable;	break;}
				case set_uart2: {SYSCTRL->APBBCKCON_b.UART2BCKE=enable;SYSCTRL->PERCKEN_b.UART2CKEN=enable;	break;}
				case set_uart1: {SYSCTRL->APBBCKCON_b.UART1BCKE=enable;SYSCTRL->PERCKEN_b.UART1CKEN=enable;	break;}
				case set_uart0: {SYSCTRL->APBBCKCON_b.UART0BCKE=enable;SYSCTRL->PERCKEN_b.UART0CKEN=enable;	break;}
				case set_flash: {SYSCTRL->AHBBCKCON_b.FLSCBCKE=enable;SYSCTRL->PERCKEN_b.FLSEPCKEN=enable;	break;}
				case set_sys: 	{SYSCTRL->AHBBCKCON_b.SYSCBCKE=enable; 																			break;}
			  case set_pmu:	  {SYSCTRL->AHBBCKCON_b.PMUBCKE=enable;																				break;}
				case set_io:	  {SYSCTRL->AHBBCKCON_b.IOCBCKE=enable;																				break;}
				case set_spi0:	{SYSCTRL->AHBBCKCON_b.SPI0BCKE=enable;																		  break;}
				case set_timer2:{SYSCTRL->APBBCKCON_b.TIMER2BCKE=enable;																		break;}
				case set_timer1:{SYSCTRL->APBBCKCON_b.TIMER1BCKE=enable;																		break;}
				case set_timer0:{SYSCTRL->APBBCKCON_b.TIMER0BCKE=enable;																		break;}
				case set_anactr:{SYSCTRL->APBBCKCON_b.ANACTLBCKE=enable;																		break;}
				case set_iwdg:	{SYSCTRL->APBBCKCON_b.IWDTBCKE=enable;																			break;}
				case set_crc:		{SYSCTRL->APBBCKCON_b.CRCBCKE=enable;																				break;}
				case set_rambist:	{SYSCTRL->APBBCKCON_b.RAMBISTBCKE=enable;																	break;}
        default: break;
   }
}
void RCC_TRIM(void)
{
	SYSCTRL->HSRCTRIM_b.HSRCTRIM=0x01BC;
}
